feat: enable translation or customization of the constants "<NULL>", "TRUE", "FALSE" and "<empty string>"#40919
Conversation
✅ Deploy Preview for superset-docs-preview ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #40919 +/- ##
==========================================
- Coverage 64.17% 64.15% -0.03%
==========================================
Files 2654 2655 +1
Lines 143763 143827 +64
Branches 33161 33166 +5
==========================================
+ Hits 92260 92272 +12
- Misses 49887 49934 +47
- Partials 1616 1621 +5
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Code Review Agent Run #f1b1a5
Actionable Suggestions - 1
-
superset-frontend/src/explore/components/controls/CollectionControl/CollectionControl.test.tsx - 1
- Mock targets non-existent export · Line 23-23
Additional Suggestions - 3
-
superset-frontend/plugins/plugin-chart-echarts/src/constants.ts - 1
-
Missing Python backend constants · Line 32-35The diff adds TRUE_STRING and FALSE_STRING with a comment directing developers to also update constants.py, but these constants are missing from the Python backend file. The existing NULL_STRING and EMPTY_STRING are already mirrored in constants.py (lines 30-31), but TRUE_STRING and FALSE_STRING are not. This creates an inconsistency that could cause issues if backend code needs to reference these values.
-
-
superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/transformProps.ts - 1
-
Dead code removal needed · Line 72-74The diff correctly changes `NULL_STRING` to `NULL_STRING()` (calling the function). However, the entire code block (lines 72-74) is dead code — after `return ''` at line 68, `series` is guaranteed truthy, making `if (!series)` at line 72 unreachable. The proper fix is to delete lines 72-74 entirely rather than fixing code that can never execute.
-
-
superset-frontend/src/components/FilterableTable/useCellContentParser.ts - 1
-
Inconsistent null label text · Line 25-25The `NULL_STRING` now returns `'NULL'` but `plugin-chart-echarts/src/constants.ts:33` uses `''` with angle brackets. Users may see inconsistent null representations depending on the displaying component.
-
Filtered by Review Rules
Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.
-
superset-frontend/plugins/plugin-chart-echarts/test/utils/series.test.ts - 1
- Test passes function instead of calling it · Line 1354-1354
Review Details
-
Files reviewed - 18 · Commit Range:
a052f97..a052f97- superset-frontend/plugins/plugin-chart-echarts/src/Bubble/transformProps.ts
- superset-frontend/plugins/plugin-chart-echarts/src/Sunburst/transformProps.ts
- superset-frontend/plugins/plugin-chart-echarts/src/Treemap/EchartsTreemap.tsx
- superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/transformProps.ts
- superset-frontend/plugins/plugin-chart-echarts/src/constants.ts
- superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
- superset-frontend/plugins/plugin-chart-echarts/test/utils/series.test.ts
- superset-frontend/src/components/FilterableTable/useCellContentParser.test.ts
- superset-frontend/src/components/FilterableTable/useCellContentParser.ts
- superset-frontend/src/components/FilterableTable/utils.tsx
- superset-frontend/src/explore/components/controls/CollectionControl/CollectionControl.test.tsx
- superset-frontend/src/explore/exploreUtils/getSimpleSQLExpression.test.ts
- superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx
- superset-frontend/src/filters/utils.test.ts
- superset-frontend/src/filters/utils.ts
- superset-frontend/src/utils/common.test.tsx
- superset-frontend/src/utils/common.ts
- superset/constants.py
-
Files skipped - 0
-
Tools
- Whispers (Secret Scanner) - ✔︎ Successful
- Detect-secrets (Secret Scanner) - ✔︎ Successful
- Eslint (Linter) - ✔︎ Successful
- MyPy (Static Code Analysis) - ✔︎ Successful
- Astral Ruff (Static Code Analysis) - ✔︎ Successful
Bito Usage Guide
Commands
Type the following command in the pull request comment and save the comment.
-
/review- Manually triggers a full AI review. -
/pause- Pauses automatic reviews on this pull request. -
/resume- Resumes automatic reviews. -
/resolve- Marks all Bito-posted review comments as resolved. -
/abort- Cancels all in-progress reviews.
Refer to the documentation for additional commands.
Configuration
This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.
Documentation & Help
| import CollectionControl from '.'; | ||
|
|
||
| jest.mock('@superset-ui/chart-controls', () => ({ | ||
| ...jest.requireActual('@superset-ui/chart-controls'), |
There was a problem hiding this comment.
The mock targets InfoTooltip from @superset-ui/chart-controls, but this component is not exported from that module. The actual source imports InfoTooltip from @superset-ui/core/components (see ControlHeader.tsx:22). This mock will have no effect and may cause test failures.
Code suggestion
Check the AI-generated fix before applying
--- superset-frontend/src/explore/components/controls/CollectionControl/CollectionControl.test.tsx
+++ superset-frontend/src/explore/components/controls/CollectionControl/CollectionControl.test.tsx
@@ -19,7 +19,7 @@ import { render, screen, userEvent } from 'spec/helpers/testing-library';
import CollectionControl from '.';
jest.mock('@superset-ui/chart-controls', () => ({
- ...jest.requireActual('@superset-ui/chart-controls'),
+ ...jest.requireActual('@superset-ui/chart-controls'),
InfoTooltip: (props: any) => (
<button
onClick={props.onClick}
type="button"
data-icon={props.icon}
data-tooltip={props.tooltip}
>
{props.label}
</button>
),
}));
jest.mock('@superset-ui/core/components', () => ({
...jest.requireActual('@superset-ui/core/components'),
InfoTooltip: (props: any) => (
<button
onClick={props.onClick}
type="button"
data-icon={props.icon}
data-tooltip={props.tooltip}
>
{props.label}
</button>
),
}));
Code Review Run #f1b1a5
Should Bito avoid suggestions like this for future reviews? (Manage Rules)
- Yes, avoid them
2cc6bab to
8393ff8
Compare
There was a problem hiding this comment.
Code Review Agent Run #91c55e
Actionable Suggestions - 2
-
superset-frontend/plugins/plugin-chart-echarts/src/constants.ts - 1
- Documentation Inconsistency · Line 30-30
-
superset/constants.py - 1
- Use lazy_gettext for module constants · Line 26-26
Additional Suggestions - 1
-
superset-frontend/src/utils/common.ts - 1
-
Overly specific type annotation · Line 45-45The type 'ReturnType' is overly specific. Since all four constants are functions returning strings, using 'string' would be simpler and more maintainable.
-
Filtered by Review Rules
Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.
-
superset-frontend/plugins/plugin-chart-echarts/src/Bubble/transformProps.ts - 1
- Missing function invocation · Line 148-148
Review Details
-
Files reviewed - 18 · Commit Range:
58077d8..8393ff8- superset-frontend/plugins/plugin-chart-echarts/src/Bubble/transformProps.ts
- superset-frontend/plugins/plugin-chart-echarts/src/Sunburst/transformProps.ts
- superset-frontend/plugins/plugin-chart-echarts/src/Treemap/EchartsTreemap.tsx
- superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/transformProps.ts
- superset-frontend/plugins/plugin-chart-echarts/src/constants.ts
- superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts
- superset-frontend/plugins/plugin-chart-echarts/test/utils/series.test.ts
- superset-frontend/src/components/FilterableTable/useCellContentParser.test.ts
- superset-frontend/src/components/FilterableTable/useCellContentParser.ts
- superset-frontend/src/components/FilterableTable/utils.tsx
- superset-frontend/src/explore/components/controls/CollectionControl/CollectionControl.test.tsx
- superset-frontend/src/explore/exploreUtils/getSimpleSQLExpression.test.ts
- superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx
- superset-frontend/src/filters/utils.test.ts
- superset-frontend/src/filters/utils.ts
- superset-frontend/src/utils/common.test.tsx
- superset-frontend/src/utils/common.ts
- superset/constants.py
-
Files skipped - 0
-
Tools
- Whispers (Secret Scanner) - ✔︎ Successful
- Detect-secrets (Secret Scanner) - ✔︎ Successful
- Eslint (Linter) - ✔︎ Successful
- MyPy (Static Code Analysis) - ✔︎ Successful
- Astral Ruff (Static Code Analysis) - ✔︎ Successful
Bito Usage Guide
Commands
Type the following command in the pull request comment and save the comment.
-
/review- Manually triggers a full AI review. -
/pause- Pauses automatic reviews on this pull request. -
/resume- Resumes automatic reviews. -
/resolve- Marks all Bito-posted review comments as resolved. -
/abort- Cancels all in-progress reviews.
Refer to the documentation for additional commands.
Configuration
This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.
Documentation & Help
|
|
||
| // eslint-disable-next-line import/prefer-default-export | ||
| export const NULL_STRING = '<NULL>'; | ||
| // ATTENTION: If you change any constants, make sure to also change constants.py |
There was a problem hiding this comment.
The comment at line 30 states 'If you change any constants, make sure to also change constants.py', but the new TRUE_STRING and FALSE_STRING constants lack Python counterparts. Either update the comment to scope it to NULL_STRING/EMPTY_STRING, or add the new constants to Python to honor the stated contract.
Code Review Run #91c55e
Should Bito avoid suggestions like this for future reviews? (Manage Rules)
- Yes, avoid them
|
|
||
| from superset.utils.backports import StrEnum | ||
|
|
||
| from flask_babel import gettext as __ |
There was a problem hiding this comment.
Using gettext for module-level constants can fail when the module is imported before a request context is established. The codebase consistently uses lazy_gettext for constants (see initialization/__init__.py:33 comment: 'using lazy_gettext since initialization happens prior to the request scope'). This pattern is verified across 20+ files importing lazy_gettext for similar use cases.
Code suggestion
Check the AI-generated fix before applying
--- a/superset/constants.py
+++ b/superset/constants.py
@@ -23,7 +23,7 @@
from superset.utils.backports import StrEnum
-from flask_babel import gettext as __
+from flask_babel import lazy_gettext as __
DEFAULT_USER_AGENT = "Apache Superset"
Code Review Run #91c55e
Should Bito avoid suggestions like this for future reviews? (Manage Rules)
- Yes, avoid them
…LL", "TRUE", "FALSE" and "<empty string>"
8393ff8 to
16d83b1
Compare
| export function optionValue( | ||
| opt: OptionValue, | ||
| ): OptionValue | typeof NULL_STRING { | ||
| ): OptionValue | ReturnType<typeof NULL_STRING> { | ||
| if (opt === null) { | ||
| return NULL_STRING; | ||
| return NULL_STRING(); | ||
| } | ||
| return opt; |
There was a problem hiding this comment.
Suggestion: Converting null into the localized display token for the option value collapses two distinct inputs (null and a real string equal to that token) into the same value, which causes ambiguous selections and incorrect round-tripping. Keep the underlying option value as null and only localize the label. [logic error]
Severity Level: Major ⚠️
- ⚠️ Option helpers collapse NULL and sentinel string values.
- ⚠️ Filters may treat real sentinel text as SQL NULL.Steps of Reproduction ✅
1. Open `superset-frontend/src/utils/common.ts` and note `optionValue` at lines 87-93 and
`optionFromValue` at lines 96-98: `optionValue` returns `NULL_STRING()` when `opt ===
null`, and `optionFromValue` uses this as the `value` field of `OptionItem`.
2. In a TypeScript runtime (or unit test), import `optionFromValue` and `NULL_STRING` from
`superset-frontend/src/utils/common.ts` (re-exported at lines 27-35) and evaluate:
```ts
const a = optionFromValue(null); // uses optionValue/optionLabel
const b = optionFromValue(NULL_STRING()); // pass a real string equal to the null token
-
Observe that
a.value === b.valuebecause fornullinputoptionValuereturns
NULL_STRING()(line 90-91), while forNULL_STRING()inputoptionValuereturns the
same string unchanged (line 93), even though the original inputs (nullvs actual string)
are different. -
Any consumer using
OptionItem.value(typeOptionValue | ReturnType<typeof NULL_STRING>at line 45) for identity, selection, or to build backend filter payloads can
no longer distinguish database rows whose actual value equals the localized null token
from rows that are trulyNULL, leading to ambiguous selections and incorrect
round-tripping once this helper is used in production code.
</details>
[Fix in Cursor](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=efed6b1328d448b0bfef093d2a8cc056&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset) | [Fix in VSCode Claude](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=efed6b1328d448b0bfef093d2a8cc056&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
*(Use Cmd/Ctrl + Click for best experience)*
<details>
<summary><b>Prompt for AI Agent 🤖 </b></summary>
```mdx
This is a comment left during a code review.
**Path:** superset-frontend/src/utils/common.ts
**Line:** 87:93
**Comment:**
*Logic Error: Converting `null` into the localized display token for the option `value` collapses two distinct inputs (`null` and a real string equal to that token) into the same value, which causes ambiguous selections and incorrect round-tripping. Keep the underlying option value as `null` and only localize the label.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
| from flask_babel import gettext as __ | ||
|
|
||
| from superset.utils.backports import StrEnum | ||
|
|
||
| DEFAULT_USER_AGENT = "Apache Superset" | ||
|
|
||
| NULL_STRING = "<NULL>" | ||
| EMPTY_STRING = "<empty string>" | ||
| NULL_STRING = __("<NULL>") | ||
| EMPTY_STRING = __("<empty string>") |
There was a problem hiding this comment.
Suggestion: gettext is being executed at module import time, so these translated constants are resolved once (typically in the default locale) and then reused for all requests. That breaks per-user localization and can also desynchronize frontend/backend sentinel values across locales. Use lazy translation (or translate at usage time) so the value is resolved in the active request locale. [logic error]
Severity Level: Critical 🚨
- ⚠️ NULL and empty tokens ignore active request locale.
- ⚠️ Frontend and backend NULL sentinels diverge across locales.Steps of Reproduction ✅
1. Open `superset/constants.py` and note at lines 24-31 that `gettext` is imported as `__`
and immediately invoked to define `NULL_STRING = __("<NULL>")` and `EMPTY_STRING =
__("<empty string>")`, so these translations are resolved once at module import time.
2. In a Flask context, demonstrate locale sensitivity by comparing:
- `from flask_babel import gettext as __; __("<NULL>")` executed inside a
`force_locale("fr")` block (returns French translation), versus
- `from superset.constants import NULL_STRING; NULL_STRING` inside the same block
(still returns the value computed when `superset.constants` was first imported,
typically English), proving `NULL_STRING` is not per-request localized.
3. Open `superset/utils/pandas_postprocessing/pivot.py` and observe `pivot()` at lines
10-32, where the `column_fill_value` default is `NULL_STRING` (line 17-31 comment). When a
chart query uses the pivot post-processing operation (wired via
`superset/utils/pandas_postprocessing/__init__.py:17-31` and the generic post-processing
pipeline), any missing column labels are filled with this frozen constant, so users on
non-default locales see the startup-locale token instead of a value in their active
locale.
4. Open `superset/models/helpers.py` around lines 2520-2533 and note `handle_single_value`
compares incoming filter values against `NULL_STRING` and `EMPTY_STRING` (lines 2520-2523)
to turn those sentinel strings back into `None` or `""`. On the frontend, the
corresponding constants are defined in
`superset-frontend/plugins/plugin-chart-echarts/src/constants.ts:32-35` as functions
`NULL_STRING()`/`EMPTY_STRING()` that call `t('<NULL>')`/`t('<empty string>')` per current
UI locale. Because the backend constants are frozen at import time, for users whose locale
differs from the server's startup locale the frontend's localized sentinel strings may no
longer equal the backend's `NULL_STRING`/`EMPTY_STRING`, causing null/empty filters not to
be recognized and desynchronizing frontend and backend sentinel handling across locales.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset/constants.py
**Line:** 24:31
**Comment:**
*Logic Error: `gettext` is being executed at module import time, so these translated constants are resolved once (typically in the default locale) and then reused for all requests. That breaks per-user localization and can also desynchronize frontend/backend sentinel values across locales. Use lazy translation (or translate at usage time) so the value is resolved in the active request locale.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| data.forEach(datum => { | ||
| const dataName = bubbleSeries ? datum[bubbleSeries] : datum[entity]; | ||
| const name = dataName ? String(dataName) : NULL_STRING; | ||
| const name = dataName ? String(dataName) : NULL_STRING(); |
There was a problem hiding this comment.
Suggestion: The null fallback uses a truthy check, so valid category values like 0, false, and '' are incorrectly converted to the null label. This will merge distinct categories into the null bucket and produce incorrect legend/color grouping. Check explicitly for null/undefined instead of falsy values. [falsy zero check]
Severity Level: Major ⚠️
- ⚠️ Bubble chart merges 0-category into null legend bucket.
- ⚠️ Bubble legend mislabels falsy category values as null.Steps of Reproduction ✅
1. In the frontend, `MainPreset` registers `EchartsBubbleChartPlugin` with key
`VizType.Bubble` at `superset-frontend/src/visualizations/presets/MainPreset.ts:198`,
which pulls `BubbleTransformProps` from `@superset-ui/plugin-chart-echarts` (re-exported
in `superset-frontend/plugins/plugin-chart-echarts/src/index.ts:11` as the default from
`./Bubble/transformProps`).
2. Prepare bubble chart form data similar to the unit test
(`superset-frontend/plugins/plugin-chart-echarts/test/Bubble/transformProps.test.ts:10-33`),
but use a dataset where the grouping column (e.g. `entity`/`customer_name`) contains a
legitimate falsy value such as `0` or `''` for one row in `queriesData[0].data` (see
structure at lines 35-58 in that test).
3. When `transformProps` runs in
`superset-frontend/plugins/plugin-chart-echarts/src/Bubble/transformProps.ts:98-169`, it
iterates `data.forEach(datum => { ... })` at line 146, computes `dataName = bubbleSeries ?
datum[bubbleSeries] : datum[entity];` at line 147, and for the row where `datum[entity]`
is `0` or `''`, `dataName` is that falsy value.
4. At line 148, `const name = dataName ? String(dataName) : NULL_STRING();` treats
`0`/`''` as falsy, so `name` becomes `NULL_STRING()` instead of `'0'`/`''`, and the
legend/series name added at lines 151-169 uses the null label; this collapses the real
`0`/empty-string category into the `<NULL>` bucket, producing incorrect legend entries and
color grouping for that category.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-echarts/src/Bubble/transformProps.ts
**Line:** 148:148
**Comment:**
*Falsy Zero Check: The null fallback uses a truthy check, so valid category values like `0`, `false`, and `''` are incorrectly converted to the null label. This will merge distinct categories into the null bucket and produce incorrect legend/color grouping. Check explicitly for `null`/`undefined` instead of falsy values.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| const drillByFilters: BinaryQueryObjectFilterClause[] = []; | ||
| treePath.forEach((path, i) => { | ||
| const val = path === 'null' ? NULL_STRING : path; | ||
| const val = path === 'null' ? NULL_STRING() : path; |
There was a problem hiding this comment.
Suggestion: Mapping the literal string 'null' to the null token changes semantics for real string values equal to "null", so drill filters can target the wrong records. Preserve the original value unless you can reliably detect an actual null sentinel from the source data. [incorrect condition logic]
Severity Level: Major ⚠️
- ⚠️ Treemap drill-to-detail misfilters literal 'null' category.
- ⚠️ Treemap drill-by filters mis-target literal 'null' values.Steps of Reproduction ✅
1. `MainPreset` wires `EchartsTreemapChartPlugin` into the visualization registry with key
`VizType.Treemap` at `superset-frontend/src/visualizations/presets/MainPreset.ts:125`, and
the plugin uses `EchartsTreemap` from
`superset-frontend/plugins/plugin-chart-echarts/src/Treemap/EchartsTreemap.tsx` as its
React chart component.
2. In `Treemap` transform props
(`superset-frontend/plugins/plugin-chart-echarts/src/Treemap/transformProps.ts:170-187`),
leaf node names are derived via `formatSeriesName(...)`; when the underlying groupby
column holds the literal string `"null"`, `formatSeriesName` (see
`superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts:41-72`) returns
`"null"` unchanged because it only special-cases `name === null || name === undefined`.
3. During rendering, ECharts supplies `treePathInfo` to event handlers and
`extractTreePathInfo`
(`superset-frontend/plugins/plugin-chart-echarts/src/Treemap/constants.ts:27-36`) builds
`treePath` from `pathInfo.name`, so the click/contextmenu handlers in `EchartsTreemap`
receive `treePath` elements equal to `"null"` for those categories.
4. On context menu (right-click) in `EchartsTreemap` at
`superset-frontend/plugins/plugin-chart-echarts/src/Treemap/EchartsTreemap.tsx:117-155`,
the handler iterates `treePath.forEach((path, i) => { ... })` and executes `const val =
path === 'null' ? NULL_STRING() : path;` at line 127; for a real `"null"` category this
coerces `val` to `NULL_STRING()` (e.g. `<NULL>`), so the `drillToDetailFilters` and
`drillByFilters` built at lines 128-137 use `<NULL>` instead of `"null"` as the filter
value, causing drill-to-detail/drill-by requests to target the null token rather than the
actual `"null"` string rows.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-echarts/src/Treemap/EchartsTreemap.tsx
**Line:** 127:127
**Comment:**
*Incorrect Condition Logic: Mapping the literal string `'null'` to the null token changes semantics for real string values equal to `"null"`, so drill filters can target the wrong records. Preserve the original value unless you can reliably detect an actual null sentinel from the source data.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| if (!value) { | ||
| value = NULL_STRING; | ||
| value = NULL_STRING(); | ||
| } |
There was a problem hiding this comment.
Suggestion: This condition treats all falsy x-axis values as null, so legitimate values like 0 become <NULL>. That breaks category labeling and can produce wrong axis formatting/grouping. Restrict the null substitution to null/undefined (and handle empty string separately if needed). [falsy zero check]
Severity Level: Major ⚠️
- ⚠️ Waterfall x-axis mislabels 0 or empty categories.
- ⚠️ Waterfall chart groups falsy categories into null bucket.Steps of Reproduction ✅
1. `MainPreset` registers `EchartsWaterfallChartPlugin` with key `VizType.Waterfall` in
`superset-frontend/src/visualizations/presets/MainPreset.ts:169-171`, and
`@superset-ui/plugin-chart-echarts` re-exports `WaterfallTransformProps` from
`superset-frontend/plugins/plugin-chart-echarts/src/index.ts:12` pointing to
`./Waterfall/transformProps`.
2. The unit test
`superset-frontend/plugins/plugin-chart-echarts/test/Waterfall/transformProps.test.ts:24-40`
shows how `transformProps` is invoked via `ChartProps` with `queriesData[0].data` and
formData specifying `x_axis` and `metric`; to reproduce the issue, use a similar setup but
include a row in `data` where the x-axis column (e.g. `year`) is a legitimate falsy value
like `0` or `''`.
3. When `transformProps` executes in
`superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/transformProps.ts:159-231`,
it builds `transformedData` via `transformer` (lines 224-231) and then computes
`xAxisData` at lines 323-339 by mapping each `row` to an x-axis label; for each row it
sets `value = row[xAxisName]` or `row[breakdownName]` and then reaches the block at lines
331-333.
4. At line 331, `if (!value) { value = NULL_STRING(); }` treats any falsy `value` as null,
so a legitimate x-axis value of `0`, `false`, or `''` is converted to `NULL_STRING()`
instead of remaining `0`/`false`/`''`, and the resulting x-axis categories (used in
`echartOptions.xAxis.data` at line 446) and tooltip/title formatter `xAxisFormatter`
(lines 341-351) mislabel these categories as `<NULL>`, merging them into the null bucket
and breaking category labeling and grouping.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** superset-frontend/plugins/plugin-chart-echarts/src/Waterfall/transformProps.ts
**Line:** 331:333
**Comment:**
*Falsy Zero Check: This condition treats all falsy x-axis values as null, so legitimate values like `0` become `<NULL>`. That breaks category labeling and can produce wrong axis formatting/grouping. Restrict the null substitution to `null`/`undefined` (and handle empty string separately if needed).
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
Code Review Agent Run #8ceff1Actionable Suggestions - 0Additional Suggestions - 4
Filtered by Review RulesBito filtered these suggestions based on rules created automatically for your feedback. Manage rules.
Review Details
Bito Usage GuideCommands Type the following command in the pull request comment and save the comment.
Refer to the documentation for additional commands. Configuration This repository uses Documentation & Help |
SUMMARY
This PR aims to easily allow translation or customization of the constants
<NULL>,TRUE,FALSE, and<empty string>.BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Here is an example of customizing
<NULL>into French, before and after:TESTING INSTRUCTIONS
To test this change, you must first translate the strings in question and observe the screens where they may be displayed.
ADDITIONAL INFORMATION